﻿using System;
using System.Windows;
using System.Windows.Controls;
using CThru.Silverlight;
using NUnit.Framework;
using TypeMock.ArrangeActAssert;
using System.Windows.Media.Animation;

namespace Core.Infrastructure.Test
{
    [TestFixture]
    public class AnimationServiceTest
    {
        private Action action;
        private bool wasLaunched;

        private AnimationService.AnimationService animationService;
        private Storyboard storyBoard;

        [SetUp, SilverlightSetUp]
        public void SetUpTest()
        {
            storyBoard = Isolate.Fake.Instance<Storyboard>();

            animationService = new AnimationService.AnimationService();
       
            action = () => wasLaunched = true;
            wasLaunched = false;
        }

        [TearDown]
        public void TearDownTest()
        {
            animationService = null;
            action = null;
            wasLaunched = true;
        }

        [Test, SilverlightUnitTest]
        [ExpectedException(typeof(ArgumentNullException))]
        public void PerformAnimation_ActionNull_ExceptionThrown()
        {
            animationService.PerformAnimation(null, null);
        }

        [Test, SilverlightUnitTest]
        public void PerformAnimation_EnterStoryBoardNull_ActionCalled()
        {
            animationService.PerformAnimation(action, null);

            Assert.True(wasLaunched);
        }

        [Test, SilverlightUnitTest]
        public void PerformAnimation_EnterStoryBoardNotNull_ActionNotCalled()
        {
            animationService.PerformAnimation(action, storyBoard);

            Assert.False(wasLaunched);
        }

        [Test, SilverlightUnitTest]
        public void PerformAnimation_EnterStoryBoardNotNull_BeginWasCalled()
        {
            animationService.PerformAnimation(action, storyBoard);

            Isolate.Verify.WasCalledWithAnyArguments(() => storyBoard.Begin());
        }

        [Test, SilverlightUnitTest]
        public void PerformAnimation_EnterStoryBoardNotNullStoryboardCompleted_BeginWasCalled()
        {
            animationService.PerformAnimation(action, storyBoard);

            Isolate.Invoke.Event(() => storyBoard.Completed += null, null, null);

            Assert.True(wasLaunched);
        }

        [Test, SilverlightUnitTest]
        public void EnterUIElementAnimation_Always_CallsPerformAnimation()
        {
            animationService.EnterViewVisibilityStoryboard = storyBoard;
            Isolate.WhenCalled(() => animationService.PerformAnimation(null, null)).IgnoreCall();

            animationService.EnterUIElementAnimation(action);

            Isolate.Verify.WasCalledWithExactArguments(() => animationService.PerformAnimation(action, storyBoard));
        }

        [Test, SilverlightUnitTest]
        public void LeaveUIElementAnimation_Always_CallsPerformAnimation()
        {
            animationService.LeaveViewVisibilityStoryboard = storyBoard;
            Isolate.WhenCalled(() => animationService.PerformAnimation(null, null)).IgnoreCall();

            animationService.LeaveUIElementAnimation(action);

            Isolate.Verify.WasCalledWithExactArguments(() => animationService.PerformAnimation(action, storyBoard));
        }
    }
}
